package com.hb.trade.server.project.archive.service.impl;

import cn.hutool.core.io.FileUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.json.JSONArray;
import cn.hutool.json.JSONObject;
import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hb.core.config.handler.AttachmentsTypeHandler;
import com.hb.core.pojo.Attachment;
import com.hb.core.pojo.Attachments;
import com.hb.core.pojo.project.archive.dto.ArchiveCommonFileDTO;
import com.hb.core.pojo.project.archive.dto.FileDTO;
import com.hb.core.pojo.project.archive.dto.ProjectArchiveFileDTO;
import com.hb.core.pojo.project.archive.entity.ProjectArchiveFile;
import com.hb.core.pojo.project.archive.mapper.ProjectArchiveFileMapper;
import com.hb.core.pojo.project.evaluation.entity.EvaluationSummary;
import com.hb.trade.server.project.archive.service.ProjectArchiveFileService;
import com.hb.trade.server.project.evaluation.service.EvaluationSummaryService;
import com.hb.trade.server.project.util.DateUtil;
import org.apache.commons.lang3.StringUtils;
import org.fzzn.core.util.IdUtil;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.stream.Collectors;

/**
 * <p>
 * 服务实现类
 * </p>
 *
 * @author yuezheng
 * @since 2022-02-17
 */
@Service
public class ProjectArchiveFileServiceImpl extends ServiceImpl<ProjectArchiveFileMapper, ProjectArchiveFile> implements ProjectArchiveFileService {

    @Resource
    private ProjectArchiveFileMapper projectArchiveFileMapper;

    @Resource
    private EvaluationSummaryService evaluationSummaryService;

    /**
     * 根据归档id 查询所有文件
     *
     * @param projectArchiveFileDTO
     * @return
     */
    @Override
    public Attachments getAttachmentBySectionId(ProjectArchiveFileDTO projectArchiveFileDTO) {

        List<ArchiveCommonFileDTO> archiveFileList = this.getArchiveFileList(projectArchiveFileDTO);

        Attachments result = new Attachments();

        for (ArchiveCommonFileDTO fileDTO : archiveFileList) {
            Attachments fileList = fileDTO.getFileList();
            if (fileList != null) {
                result.addAll(fileList);
            }
        }
        return result;
    }

    /**
     * 查询归档下所有文件类型和文件
     *
     * @param projectArchiveFileDTO
     * @return map
     */
    @Override
    public List<ArchiveCommonFileDTO> getArchiveFileList(ProjectArchiveFileDTO projectArchiveFileDTO) {
        AttachmentsTypeHandler typeHandler = new AttachmentsTypeHandler();

        List<ArchiveCommonFileDTO> list = getFileList(projectArchiveFileDTO.getProjectId(), projectArchiveFileDTO.getSectionId());

        Map<String, ArchiveCommonFileDTO> map = new HashMap<>();
        for (ArchiveCommonFileDTO item : list) {
            String attachment = item.getAttachments();
            String appendix = item.getAppendix();
            Attachments curr = new Attachments();
            // 判断签章文件是否为null
            if (attachment != null) {
                Attachments attachments = typeHandler.convert(attachment);
                if (attachments != null && attachments.size() > 0) {
                    if (item.getFileType().equals("投标文件") && item.getSort() == 6) {
                        Attachment atta = attachments.get(0);
                        atta.setRawFileName(item.getOrgName());
                    }
                    curr.addAll(attachments);
                }
            }
            // 判断附件是否为null
            if (appendix != null) {
                Attachments attachments = typeHandler.convert(appendix);
                if (attachments != null) {
                    curr.addAll(attachments);
                }
            }
            item.setFileList(curr);
            if (map.containsKey(item.getFileType())) {
                ArchiveCommonFileDTO archiveCommonFileDTO = map.get(item.getFileType());
                archiveCommonFileDTO.getFileList().addAll(curr);
                item = archiveCommonFileDTO;
            }
            map.put(item.getFileType(), item);
        }
        List<ArchiveCommonFileDTO> archiveFileList = this.projectArchiveFileMapper.selectTradeArchiveFile(projectArchiveFileDTO.getSectionId());

        for (ArchiveCommonFileDTO dto : archiveFileList) {
            // 如果为流程中上传的文件
            if (map.containsKey(dto.getFileType())) {

                // 处理当前页面添加的文件 添加可删除标志
                Attachments convert = typeHandler.convert(dto.getAttachments());
                List<FileDTO> attaList = convert.stream().map(item -> {
                    FileDTO atta = new FileDTO();
                    BeanUtils.copyProperties(item, atta);
                    atta.setDel(1);
                    return atta;
                }).collect(Collectors.toList());

                //获取map中原有文件类别 进行数据更新
                ArchiveCommonFileDTO fileDTO = map.get(dto.getFileType());
                Attachments attachments = fileDTO.getFileList();
                attachments.addAll(attaList);
                fileDTO.setFileList(attachments);
                map.put(fileDTO.getFileType(), fileDTO);
            } else {
                // 处理当前页面添加的文件 添加可删除标志
                Attachments convert = typeHandler.convert(dto.getAttachments());
                List<FileDTO> attaList = new ArrayList<>();
                if (convert != null) {
                    attaList = convert.stream().map(item -> {
                        FileDTO atta = new FileDTO();
                        BeanUtils.copyProperties(item, atta);
                        atta.setDel(1);
                        return atta;
                    }).collect(Collectors.toList());
                }
                // 设置基本信息 直接放入map
                Attachments attachments = new Attachments();
                attachments.addAll(attaList);
                dto.setFileList(attachments);
                dto.setSort(99);
                dto.setDel(1);
                map.put(dto.getFileType(), dto);
            }
        }
        // 如果是政府采购则修改名称
        if (projectArchiveFileDTO.getType() != null && projectArchiveFileDTO.getType().equals("1")) {
            ArchiveCommonFileDTO tradeNotice = map.get("招标公告");
            ArchiveCommonFileDTO cbgg = map.get("采购公告");
            if (cbgg != null) {
                tradeNotice.getFileList().addAll(cbgg.getFileList());
                map.remove("采购公告");
            }
            if (tradeNotice != null){
                tradeNotice.setFileType("采购公告");
            }

            ArchiveCommonFileDTO documentSignature = map.get("招标文件");
            ArchiveCommonFileDTO cgwj = map.get("采购文件");
            if (cgwj != null) {
                documentSignature.getFileList().addAll(cgwj.getFileList());
                map.remove("采购文件");
            }
            if (documentSignature != null){
                documentSignature.setFileType("采购文件");
            }

            ArchiveCommonFileDTO bidSectionTender = map.get("投标文件");
            ArchiveCommonFileDTO xywj = map.get("响应文件");
            if (xywj != null) {
                bidSectionTender.getFileList().addAll(xywj.getFileList());
                map.remove("响应文件");
            }
            bidSectionTender.setFileType("响应文件");

            ArchiveCommonFileDTO evaluation = map.get("评标报告");
            ArchiveCommonFileDTO psbg = map.get("评审报告");
            if (psbg != null) {
                evaluation.getFileList().addAll(psbg.getFileList());
                map.remove("评审报告");
            }
            evaluation.setFileType("评审报告");

            ArchiveCommonFileDTO bidCandidate = map.get("中标候选人公示");
            ArchiveCommonFileDTO cjhxr = map.get("成交候选人公示");
            if (cjhxr != null) {
                bidCandidate.getFileList().addAll(cjhxr.getFileList());
                map.remove("成交候选人公示");
            }
            bidCandidate.setFileType("成交候选人公示");

            ArchiveCommonFileDTO tradeBidWinResult = map.get("中标结果公示");
            if (tradeBidWinResult != null){
                ArchiveCommonFileDTO cjjg = map.get("成交结果公示");
                if (cjjg != null) {
                    tradeBidWinResult.getFileList().addAll(cjjg.getFileList());
                    map.remove("成交结果公示");
                }
                tradeBidWinResult.setFileType("成交结果公示");
            }

        }
        List<ArchiveCommonFileDTO> result = map.values().stream().sorted((item1, item2) -> {
            return item1.getSort() - item2.getSort();
        }).collect(Collectors.toList());
        return result;
    }


    /**
     * 添加文件
     *
     * @Param: ProjectArchiveDetailDTO
     * @return: Message<Boolean>
     * @Author: 岳争
     * @Date: 2022/2/17
     */
    @Override
    public int addArchiveType(ProjectArchiveFile projectArchiveFile) {
        projectArchiveFile.setDel(1);
        projectArchiveFile.setCreateTime(LocalDateTime.now());
        return this.projectArchiveFileMapper.insert(projectArchiveFile);
    }

    /**
     * 向类别中添加文件
     *
     * @param projectArchiveFile
     * @return
     */
    @Override
    public int addArchiveFile(ProjectArchiveFile projectArchiveFile) {
        QueryWrapper<ProjectArchiveFile> queryWrapper = new QueryWrapper<ProjectArchiveFile>();
        if (projectArchiveFile.getFileType() != null && projectArchiveFile.getSectionId() != null) {
            queryWrapper.eq("file_type", projectArchiveFile.getFileType());
            queryWrapper.eq("section_id", projectArchiveFile.getSectionId());

            ProjectArchiveFile archive = projectArchiveFileMapper.selectOne(queryWrapper);

            if (projectArchiveFile != null && projectArchiveFile.getAttachments() != null) {
                projectArchiveFile.getAttachments().get(0).setId(IdUtil.getId());
            }

            // 添加文件类型为其他表 则直接添加
            if (archive == null) {
                projectArchiveFile.setDel(1);
                return projectArchiveFileMapper.insert(projectArchiveFile);
            } else {
                // 如果该文件类型已存在文件则添加修改
                Attachments attachments = archive.getAttachments();
                if (attachments == null) {
                    ProjectArchiveFileDTO dto = new ProjectArchiveFileDTO();
                    BeanUtils.copyProperties(archive, dto);
                    String fileJson = JSONUtil.toJsonStr(projectArchiveFile.getAttachments());
                    dto.setAttachments(fileJson);
                    return this.projectArchiveFileMapper.updateArchiveFileById(dto);
                }
                attachments.addAll(projectArchiveFile.getAttachments());
                ProjectArchiveFileDTO dto = new ProjectArchiveFileDTO();
                BeanUtils.copyProperties(archive, dto);
                String fileJson = JSONUtil.toJsonStr(attachments);
                dto.setAttachments(fileJson);
                archive.setAttachments(attachments);
                return this.projectArchiveFileMapper.updateArchiveFileById(dto);
            }
        }
        return 0;
    }

    /**
     * 删除单个文件
     *
     * @Param: projectArchiveDetailDTO
     * @return: ResponseDto
     * @Author: 岳争
     * @Date: 2022/2/17
     */
    @Override
    public int removeFile(ProjectArchiveFileDTO projectArchiveFileDTO) {
        QueryWrapper<ProjectArchiveFile> queryWrapper = new QueryWrapper<>();
        if (!StringUtils.isEmpty(projectArchiveFileDTO.getSectionId()) && !StringUtils.isEmpty(projectArchiveFileDTO.getFileType())) {
            queryWrapper.eq("section_id", projectArchiveFileDTO.getSectionId());
            queryWrapper.eq("file_type", projectArchiveFileDTO.getFileType());

            ProjectArchiveFile projectArchiveFile = projectArchiveFileMapper.selectOne(queryWrapper);
            if (projectArchiveFile == null) {
                return 0;
            }

            Attachments attachments = projectArchiveFile.getAttachments();
            // 过滤掉删除文件
            List<Attachment> attachmentList = attachments.stream().filter(item -> {
                return !item.getId().equals(Long.valueOf(projectArchiveFileDTO.getFileId()));
            }).collect(Collectors.toList());

            // 重新设置文件列表
            attachments.clear();
            attachments.addAll(attachmentList);

            // 更新删除后的对象
            ProjectArchiveFileDTO dto = new ProjectArchiveFileDTO();
            BeanUtils.copyProperties(projectArchiveFile, dto);
            String fileJson = JSONUtil.toJsonStr(attachments);
            dto.setAttachments(fileJson);
            return projectArchiveFileMapper.updateArchiveFileById(dto);
        }

        return 0;
    }

    /**
     * 删除整个文件类型
     *
     * @Param: projectArchiveDetailDTO
     * @return: ResponseDto
     * @Author: 岳争
     * @Date: 2022/2/17
     */
    @Override
    public int removeType(ProjectArchiveFileDTO projectArchiveFileDTO) {
        QueryWrapper<ProjectArchiveFile> queryWrapper = new QueryWrapper<>();
        if (projectArchiveFileDTO.getFileType() != null && projectArchiveFileDTO.getFileType() != "") {
            queryWrapper.eq("file_type", projectArchiveFileDTO.getFileType());
        }
        if (projectArchiveFileDTO.getSectionId() != null && projectArchiveFileDTO.getSectionId() != "") {
            queryWrapper.eq("section_id", projectArchiveFileDTO.getSectionId());
        }
        return this.projectArchiveFileMapper.delete(queryWrapper);
    }

    /**
     * 获取所有文件类型中的文件
     *
     * @param projectId
     * @param sectionId
     * @return
     */
    private List<ArchiveCommonFileDTO> getFileList(String projectId, String sectionId) {
        List<ArchiveCommonFileDTO> result = new ArrayList<>();


        CompletableFuture<Void> async2 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectBuildProject(projectId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("建项文件");
                dto.setDel(0);
                dto.setSort(1);
                result.add(dto);
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async3 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectTradeNotice(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("招标公告");
                dto.setDel(0);
                dto.setSort(2);
                result.add(dto);
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async4 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectBiddingDocumentSignaturePdf(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("招标文件");
                dto.setDel(0);
                dto.setSort(3);
                result.add(dto);
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async5 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectControlNotice(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("控制价公告");
                dto.setDel(0);
                dto.setSort(4);
                result.add(dto);
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async6 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectTradeClarify(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("澄清文件");
                dto.setDel(0);
                dto.setSort(5);
                result.add(dto);
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async7 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectTradeBidSectionTender(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("投标文件");
                dto.setDel(0);
                dto.setSort(6);
                result.add(dto);
            }else {
                for (int i = 0; i < list.size(); i++) {
                    ArchiveCommonFileDTO archiveCommonFileDTO = list.get(i);
                    String attachments = archiveCommonFileDTO.getAttachments();
                    if(StringUtils.isNotEmpty(attachments)){
                        JSONArray jsonArray = JSONUtil.parseArray(attachments);
                        JSONObject jsonObject = JSONUtil.parseObj(jsonArray.get(0));
                        jsonObject.putOpt("id",archiveCommonFileDTO.getId() + i);
                        jsonArray.set(0,jsonObject);
                        archiveCommonFileDTO.setAttachments(JSONUtil.toJsonStr(jsonArray));
                    }
                }
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async8 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectOpening(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("开标一览表");
                dto.setDel(0);
                dto.setSort(7);
                result.add(dto);
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async9 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectVideo(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("开标大厅录制视频");
                dto.setDel(0);
                dto.setSort(8);
                result.add(dto);
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async10 = CompletableFuture.runAsync(() -> {
            EvaluationSummary evaluationSummary = evaluationSummaryService.getEvaluationSummaryBySectionId(Long.valueOf(sectionId));
            ArchiveCommonFileDTO archiveCommonFileDTO = new ArchiveCommonFileDTO();
            archiveCommonFileDTO.setFileType("评标报告");
            archiveCommonFileDTO.setSort(9);
            archiveCommonFileDTO.setDel(0);
            String reportUrl = evaluationSummary == null  ? null : (StrUtil.isNotEmpty(evaluationSummary.getFinalReportUrl()) ? evaluationSummary.getFinalReportUrl() : evaluationSummary.getReportUrl());

            if(evaluationSummary != null && StrUtil.isNotEmpty(reportUrl)){
                String extName = FileUtil.getSuffix(reportUrl);

                Attachments attachments = new Attachments();
                Attachment attachment = new Attachment();
                attachment.setId(evaluationSummary.getId()-1);
                attachment.setFileName("评标报告." + extName);
                attachment.setFileUrl(reportUrl);
                attachment.setRawFileName("评标报告");
                attachment.setExtName(extName);
                attachments.add(attachment);
                archiveCommonFileDTO.setAttachments(JSONUtil.toJsonStr(attachments));

            }
            result.add(archiveCommonFileDTO);
        });

        CompletableFuture<Void> async11 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectTradeBidCandidate(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("中标候选人公示");
                dto.setDel(0);
                dto.setSort(10);
                result.add(dto);
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async12 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectTradeBidWinResult(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("中标结果公示");
                dto.setDel(0);
                dto.setSort(11);
                result.add(dto);
            }
            result.addAll(list);
        });

        CompletableFuture<Void> async13 = CompletableFuture.runAsync(() -> {
            List<ArchiveCommonFileDTO> list = this.projectArchiveFileMapper.selectContract(sectionId);
            if (list == null || list.size() < 1) { // 若为null 则设置默认
                ArchiveCommonFileDTO dto = new ArchiveCommonFileDTO();
                dto.setFileType("合同附件");
                dto.setDel(0);
                dto.setSort(12);
                result.add(dto);
            }
            result.addAll(list);
        });
        CompletableFuture<Void> async14 = CompletableFuture.runAsync(() -> {
            EvaluationSummary evaluationSummary = evaluationSummaryService.getEvaluationSummaryBySectionId(Long.valueOf(sectionId));
            ArchiveCommonFileDTO archiveCommonFileDTO = new ArchiveCommonFileDTO();
            String sheetUrl = evaluationSummary == null  ? null : (StrUtil.isNotEmpty(evaluationSummary.getFinalSheetUrl()) ? evaluationSummary.getFinalSheetUrl() : evaluationSummary.getSheetUrl());

            archiveCommonFileDTO.setFileType("评分汇总");
            archiveCommonFileDTO.setSort(13);
            archiveCommonFileDTO.setDel(0);

            if(evaluationSummary != null && StrUtil.isNotEmpty(sheetUrl)){
                String extName = FileUtil.getSuffix(sheetUrl);
                if ("xlsx".equals(extName)){
                    extName = "xls";
                }
                Attachments attachments = new Attachments();
                Attachment attachment = new Attachment();
                attachment.setId(evaluationSummary.getId());
                attachment.setFileName("评分汇总." + extName);
                attachment.setFileUrl(sheetUrl);
                attachment.setRawFileName("评分汇总");
                attachment.setExtName(extName);
                attachments.add(attachment);
                archiveCommonFileDTO.setAttachments(JSONUtil.toJsonStr(attachments));
            }
            result.add(archiveCommonFileDTO);
        });

        CompletableFuture.allOf(async2, async3, async4, async5, async6, async7, async8, async9, async10, async11, async12, async13, async14).join();

        return result;
    }
}
